iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
JavaScript

JS 核心重構:勇者轉職傳說系列 第 7

Day 06:原理篇 —— 影印術!展開運算子 ...:破解傳址詛咒的終極神技

  • 分享至 

  • xImage
  •  

本文同步分享於個人部落格:Liwen Chiou | Digital Architect & Full-Stack Engineer


📜 這裡的修煉規則:

孩子,在踏上今日的領地前,先坐下來喝杯酒吧。
修煉的路很長,別急著奔跑,先聽聽這份卷軸裡的古老叮嚀。

我在每一站的盡頭都為你鋪設了 實戰演武場 CodePen。那不只是程式碼的拼湊,而是你在這場暴風雨中,試圖用邏輯點燃的一顆星火。
成功突圍後,別忘了帶著你的戰利品回到 QuestBoard 佈告欄。在那裡,你會發現自己從不孤單,公會的夥伴們都正舉杯等待你的歸來。

記住...

導師看重的從來不是你的劍法有多華麗,而是當你被邏輯擊潰、滿身泥濘後,依然選擇握緊理性的劍柄,再次向真相發起衝鋒的勇氣。


🛡️ 【公會大廳:導師的修煉導讀】

「還記得昨天那個『藍色鎧甲變紅色』的靈異事件嗎?」我推開公會圖書館中一台發著微光的舊機器——那是祕傳的影印裝置。

在 JavaScript 的世界裡,物件與陣列的靈魂是連在一起的。只要你稍不留神分享了鑰匙,兩者的命運就會被強制綁架。今天,我要教你公會最強的保命符—— 「展開運算子 (...)」。這招能幫你瞬間斷開與原版資料的「靈魂連結」,還能讓你像玩樂高一樣,自由地合併、擴充與更新你的戰備物資!


💡 【導師講義:底層真相探究】

1. 打破容器的「爆破影印術」

展開運算子 ... 的動作極其簡單:它就是把裝在「陣列」或「物件」裡的舊物資全部「倒出來」,放在空中供你重新運用。

const oldScrolls = ["火球術", "治癒術"];

// ✅ 影印術:變出一個新木箱 [],再把舊捲軸 ... 倒進去
const newScrolls = [...oldScrolls, "傳送術"];

console.log(newScrolls); // ["火球術", "治癒術", "傳送術"]
console.log(oldScrolls); // ["火球術", "治癒術"] (原版毫髮無傷,連結已斷開!)

2. 資料重組的「合併與覆蓋」

影印術最強的地方在於,你可以在合併的瞬間,對資料進行「進化」。

const baseSkill = { category: "魔法", mp: 10 };
const fireball = { name: "火球術", mp: 50 };

// ✅ 兩組合併:後面的內容會蓋掉前面的内容 (Overwriting)
// 就像是在新箱子裡先放舊零件,再把改良零件丟進去,重複的會被替換。
const superFireball = {
  ...baseSkill,
  ...fireball,
  level: "Max",
};

console.log(superFireball);
// { category: "魔法", name: "火球術", mp: 50, level: "Max" }

🏹 導師的辨析圖:影印與連結

修煉招式 標籤賦值 (=) 展開影印 (...)
核心結果 共享同一把鑰匙 打造全新實體
修改副作用 A 改,B 跟著變 各走各路,互不干擾
記憶體狀態 指向同一個地址 產生獨立新地址

3. 邏輯流向圖解

導師的圖解心法: 想像這是一個 「影印現場」。展開運算子就像是一台快速影印機,它把大箱子(物件)的殼印了一份,但裡面的貴重保險箱(嵌套物件)依然只有一張 「同樣的提貨單」。而深拷貝則是直接派人去另一個城市,重新打造了一個完全一模一樣、且內外都獨立的新保箱。

影印術邏輯圖


⚔️ 【戰術對抗:學長與學弟的代碼對決】

招式示範:小隊集結 (陣列合併)

❌ 冒險學弟:吃力的「手動接龍」

  • 負能量評級:🔴 寫法生硬 / 🔴 難以閱讀
const teamA = ["戰士", "法師"];
const teamB = ["牧師", "弓箭手"];

// 雖然能用 concat,但在多組數據合併時會變得很混亂
const fullTeam = teamA.concat(teamB);

✅ 勇者學長:直覺的「空投合併」

  • 利潤評級:🟢 極致優雅 / 🟢 一目瞭然
const teamA = ["戰士", "法師"];
const teamB = ["牧師", "弓箭手"];

// 像把兩個麻袋直接打開倒進大麻袋一樣簡單
const fullTeam = [...teamA, ...teamB];

導師講評: 學長的寫法就像是在戰場上同時召喚兩支軍隊,你一眼就能看出最終的「大名單」長什麼樣子。這就是程式碼的「描述力」。


🏰 【勇者精英課:邁向職人的進階架構】

1. 影印機的極限:淺拷貝 (Shallow Copy)

孩子,別以為 ... 是無敵的。它雖然會影印大箱子,但如果箱子裡還裝著 「另一個小箱子」,影印機印出來的依然是 同一把小箱子的鑰匙

const hero = { name: "辛梅爾", bag: { coin: 10 } };
const clone = { ...hero };

clone.bag.coin = 999;
console.log(hero.bag.coin); // 999 (救命!裡層物件還是連著的!)

當你處理「多層嵌套」的物資時,請記得:展開運算子只管第一層。

2. 終極影印:深拷貝 (Deep Copy)

當你的寶箱裡疊了好幾層箱子(嵌套物件)時,我們需要施展更徹底的「次元斷開術」。

  • 招式 A:次元切割術 (JSON.parse/stringify)
    這是公會裡最古老也最常用的招式。我們先將整個物件轉化為 「無靈魂的字串 (JSON)」,再將字串重新生成為一個 「全新的物件」

    const hero1 = { name: "勇者", bag: { coin: 10 } };
    const hero2 = JSON.parse(JSON.stringify(hero1)); // ✂️ 徹底斷開!
    
    hero2.bag.coin = 999;
    console.log(hero1.bag.coin); // 10 (成功守衛!第一、二層都不再連動)
    

    導師叮嚀: 此招雖然強大,但它會遺忘物件裡的「魔法招式 (Function)」與「特殊印記 (Symbol)」。

  • 招式 B:高階影印機 (structuredClone())
    這是近年來公會引進的最高階武器。它能無損複製循環引用與特殊數據類型,但它極度排斥 「魔法函式 (Function)」

    ⚔️ 職人級警告: 如果你的物件裡藏著咒語(函式),發動 structuredClone() 會導致 「次元崩潰 (DataCloneError)」。這就是為什麼資深前輩會說:「深拷貝資料時,請確保裡面只裝著純粹的物資,不要裝著會動的靈魂。」

3. 其餘參數 (Rest Parameters):剩下的都進口袋!

除了「倒出來」,... 還能當作 「萬能麻袋」,把它放在函式的接收處,它能捕捉所有剩餘的資料。

function captureLoot(firstGold, ...others) {
  console.log(`金幣:${firstGold}`);
  console.log(`其餘雜物:`, others); // others 自動變成陣列
}

🛖 【營火叮嚀:導師的經驗談】

孩子,導師當年維護「世界地圖物件」時,因為不懂 ... 的重要性,直接
const newMap = currentMap;
就去修改地圖上的魔王城位置。

結果那一秒,全伺服器的冒險者看到的地圖都亂了套,原本的新手村旁邊突然出現了魔王。那天我收到了公會歷史上最多的投訴信。

記住:「如果你打算修改某份前人傳下來的物件,請先『影印一份新的』再動手。這是身為資深勇者最基本的溫柔。」


天色微亮,營火雖已燃盡,但你眼中卻閃爍著領悟的光芒。在前往演武場挑戰關卡前,我已經幫你把靈魂碎片精煉成了這份「戰術錦囊」。拿好它,今日的任務不再是負擔,而是你證明自我的舞台。去吧,公會的英雄榜在等著你的戰報。

📝 【夥伴筆記:今日修煉精華】

這份筆記是你的隨身護身符,卡關時看一眼,真相就在裡面。
  • 語法特徵:三個點 ...,用於拆開容器。
  • 防止副作用:用 [...old]{...old} 產生新副本,斷開傳址連結。
  • 後蓋前規則:合併多個物件時,後方的相同屬性會覆蓋前方(Update 的關鍵)。
  • 萬能口袋:在參數處使用 ... 收集剩餘資料。

🎯 【實戰演武場】

📜 本日實戰任務:影印術與麻袋收集器 (CodePen)
🛡️ 任務達成證明:QuestBoard 公會報到處

  1. 📜 本日實戰任務:影印術與麻袋收集器 (CodePen)
  2. 將 CodePen 網址貼至 QuestBoard,並回填鑑定報告:
    • 初心者:影印術掌握度 (成就感發掘)
      • 1.今天成功使用 ... 斷開影子分身的那一刻,你有沒有感受到數據終於「受你控制」的自由感?
    • 冒險者:影印機的選擇 (理性挑戰)[⚡ 觀念辨析]
        1. 如果我的裝備物件 gear 裡面裝著一個「自動修復函式 (Function)」,為什麼使用 JSON.parse(JSON.stringify()) 影印後,這招魔法會消失不見?
  3. 任務完成後,你的名字將永遠標記在公會的英雄榜上!

📚 【圖書館卷軸:延伸學習】


上一篇
Day 05:原理篇 —— 改了 A 卻壞了 B?記憶體傳址與副本的真相
下一篇
Day 07:原理篇 —— 記憶膠囊:閉包與守護結界
系列文
JS 核心重構:勇者轉職傳說11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言